---
title: Using args
description: Guide for defining field args in Pothos
---

Similar to the [Fields Guide](./fields), the examples here will mostly be for the Query type, but
the same patterns can be used anywhere that arguments for fields can be defined, including both
Object and Interface types.

## Scalars

Scalar args can be defined a couple of different ways

### Using the `t.arg` method

```typescript
const Query = builder.queryType({
  fields: (t) => ({
    string: t.string({
      args: {
        string: t.arg({
          type: 'String',
          description: 'String arg',
        }),
      },
      resolve: (parent, args) => args.string,
    }),
  }),
});
```

### Using convenience methods

```typescript
const Query = builder.queryType({
  fields: (t) => ({
    withArgs: t.stringList({
      args: {
        id: t.arg.id(),
        int: t.arg.int(),
        float: t.arg.float(),
        boolean: t.arg.boolean(),
        string: t.arg.string(),
        idList: t.arg.idList(),
        intList: t.arg.intList(),
        floatList: t.arg.floatList(),
        booleanList: t.arg.booleanList(),
        stringList: t.arg.stringList(),
      },
      resolve: (root, args) => Object.keys(args),
    }),
  }),
});
```

## Other types

Args of non-scalar types can also be created with the `t.arg` method.

Valid arg types include `Scalars`, `Enums`, and `Input` types.

```typescript
const LengthUnit = builder.enumType('LengthUnit', {
  values: { Feet: {}, Meters: {} },
});

const Giraffe = builder.objectType('Giraffe', {
  fields: t => ({
    height: t.float({
      args: {
        unit: t.arg({
          type: LengthUnit,
        }),
      },
      resolve: (parent, args) =>
        args.unit === 'Feet' ? parent.heightInMeters * 3.281 : parent.heightInMeters,
    }),
  }),
}));
```

## Required args

Arguments are optional by default, but can be made required by passing `required: true` in the
argument options. This default can be changed in the SchemaBuilder constructor, see
[Changing Default Nullability](./changing-default-nullability).

```typescript
const Query = builder.queryType({
  fields: (t) => ({
    nullableArgs: t.stringList({
      args: {
        optional: t.arg.string(),
        required: t.arg.string({ required: true }),
        requiredList: t.arg.stringList({ required: true }),
        sparseList: t.stringList({
          required: {
            list: true,
            items: false,
          },
        }),
      },
      resolve: (parent, args) => Object.keys(args),
    }),
  }),
});
```

Note that by default even if a list arg is optional, the items in that list are not. The last
argument in the example above shows how you can make list items optional.

## Lists

To create a list argument, you can wrap the type in an array or use one of the helpers

```typescript
const Query = builder.queryType({
  fields: (t) => ({
    giraffeNameChecker: t.booleanList({
      args: {
        names: t.arg.stringList({
          required: true,
        }),
        moreNames: t.arg({
          type: ['String'],
          required: true,
        }),
      },
      resolve: (parent, args) => {
        return [...args.names, ...args.moreNames].filter((name) =>
          ['Gina', 'James'].includes(name),
        );
      },
    }),
  }),
});
```

## Nested Lists

You can use `t.arg.listRef` to create a list of lists

```typescript
const Query = builder.queryType({
  fields: (t) => ({
    example: t.boolean({
      args: {
        listOfListOfStrings: t.arg({
          type: t.arg.listRef(t.arg.listRef('String')),
        }),
        listOfListOfNullableStrings: t.arg({
          type: t.arg.listRef(
            // By default listRef creates a list of Non-null items
            // This can be overridden by passing in required: false
            t.arg.listRef('String', { required: false }),
            { required: true },
          ),
        }),
      },
      resolve: (parent, args) => {
        return true;
      },
    }),
  }),
});
```
